#include "ffmpeg_kit_wrapper.h"
#include "logger.h"
#include <jni.h>

FFmpegKitWrapper::FFmpegKitWrapper() 
    : jvm_(nullptr)
    , ffmpegKit_(nullptr)
    , ffmpegKitClass_(nullptr)
    , getMediaInformationMethod_(nullptr)
    , executeMethod_(nullptr)
    , isInitialized_(false)
    , isPlaying_(false)
    , currentTime_(0.0)
    , duration_(0.0) {
}

FFmpegKitWrapper::~FFmpegKitWrapper() {
    cleanup();
}

bool FFmpegKitWrapper::initialize() {
    if (isInitialized_) {
        return true;
    }
    
    if (!setupJNI()) {
        Logger::getInstance().log(Logger::ERROR, "Failed to setup JNI");
        return false;
    }
    
    isInitialized_ = true;
    Logger::getInstance().log(Logger::INFO, "FFmpegKit initialized successfully");
    return true;
}

bool FFmpegKitWrapper::setupJNI() {
    // 获取JNI环境
    JNIEnv* env;
    if (jvm_->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK) {
        return false;
    }
    
    // 获取FFmpegKit类
    jclass localClass = env->FindClass("com/arthenica/ffmpegkit/FFmpegKit");
    if (!localClass) {
        Logger::getInstance().log(Logger::ERROR, "FFmpegKit class not found");
        return false;
    }
    
    ffmpegKitClass_ = (jclass)env->NewGlobalRef(localClass);
    env->DeleteLocalRef(localClass);
    
    // 获取方法ID
    getMediaInformationMethod_ = env->GetStaticMethodID(
        ffmpegKitClass_, 
        "getMediaInformation", 
        "(Ljava/lang/String;)Lcom/arthenica/ffmpegkit/MediaInformation;"
    );
    
    executeMethod_ = env->GetStaticMethodID(
        ffmpegKitClass_,
        "execute",
        "(Ljava/lang/String;)Lcom/arthenica/ffmpegkit/FFmpegSession;"
    );
    
    if (!getMediaInformationMethod_ || !executeMethod_) {
        Logger::getInstance().log(Logger::ERROR, "Failed to get method IDs");
        return false;
    }
    
    return true;
}

bool FFmpegKitWrapper::openMedia(const std::string& filePath) {
    if (!isInitialized_) {
        Logger::getInstance().log(Logger::ERROR, "FFmpegKit not initialized");
        return false;
    }
    
    JNIEnv* env;
    if (jvm_->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK) {
        return false;
    }
    
    // 创建Java字符串
    jstring jFilePath = env->NewStringUTF(filePath.c_str());
    
    // 调用getMediaInformation方法
    jobject mediaInfo = env->CallStaticObjectMethod(
        ffmpegKitClass_, 
        getMediaInformationMethod_, 
        jFilePath
    );
    
    env->DeleteLocalRef(jFilePath);
    
    if (!mediaInfo) {
        Logger::getInstance().log(Logger::ERROR, "Failed to get media information");
        return false;
    }
    
    // 解析媒体信息
    jclass mediaInfoClass = env->GetObjectClass(mediaInfo);
    
    // 获取时长
    jmethodID getDurationMethod = env->GetMethodID(mediaInfoClass, "getDuration", "()Ljava/lang/String;");
    if (getDurationMethod) {
        jstring durationStr = (jstring)env->CallObjectMethod(mediaInfo, getDurationMethod);
        if (durationStr) {
            const char* durationCStr = env->GetStringUTFChars(durationStr, nullptr);
            duration_ = std::atof(durationCStr);
            env->ReleaseStringUTFChars(durationStr, durationCStr);
            env->DeleteLocalRef(durationStr);
        }
    }
    
    // 获取比特率
    jmethodID getBitrateMethod = env->GetMethodID(mediaInfoClass, "getBitrate", "()Ljava/lang/String;");
    if (getBitrateMethod) {
        jstring bitrateStr = (jstring)env->CallObjectMethod(mediaInfo, getBitrateMethod);
        if (bitrateStr) {
            const char* bitrateCStr = env->GetStringUTFChars(bitrateStr, nullptr);
            // 解析比特率
            env->ReleaseStringUTFChars(bitrateStr, bitrateCStr);
            env->DeleteLocalRef(bitrateStr);
        }
    }
    
    env->DeleteLocalRef(mediaInfo);
    env->DeleteLocalRef(mediaInfoClass);
    
    Logger::getInstance().log(Logger::INFO, "Media opened successfully: " + filePath);
    return true;
}

FFmpegKitWrapper::MediaInfo FFmpegKitWrapper::getMediaInfo() {
    MediaInfo info = {0, 0, 0.0, 0, ""};
    
    if (!isInitialized_) {
        return info;
    }
    
    info.duration = duration_;
    info.bitrate = 0; // 从之前的解析中获取
    
    return info;
}

bool FFmpegKitWrapper::play() {
    if (!isInitialized_) {
        return false;
    }
    
    isPlaying_ = true;
    Logger::getInstance().log(Logger::INFO, "Playback started");
    return true;
}

bool FFmpegKitWrapper::pause() {
    isPlaying_ = false;
    Logger::getInstance().log(Logger::INFO, "Playback paused");
    return true;
}

bool FFmpegKitWrapper::stop() {
    isPlaying_ = false;
    currentTime_ = 0.0;
    Logger::getInstance().log(Logger::INFO, "Playback stopped");
    return true;
}

bool FFmpegKitWrapper::seek(double time) {
    if (!isInitialized_) {
        return false;
    }
    
    currentTime_ = time;
    Logger::getInstance().log(Logger::INFO, "Seeked to: " + std::to_string(time));
    return true;
}

void FFmpegKitWrapper::setVolume(double volume) {
    Logger::getInstance().log(Logger::INFO, "Volume set to: " + std::to_string(volume));
}

void FFmpegKitWrapper::cleanup() {
    cleanupJNI();
    isInitialized_ = false;
    isPlaying_ = false;
}

void FFmpegKitWrapper::cleanupJNI() {
    if (jvm_) {
        JNIEnv* env;
        if (jvm_->GetEnv((void**)&env, JNI_VERSION_1_6) == JNI_OK) {
            if (ffmpegKitClass_) {
                env->DeleteGlobalRef(ffmpegKitClass_);
                ffmpegKitClass_ = nullptr;
            }
            
            if (ffmpegKit_) {
                env->DeleteGlobalRef(ffmpegKit_);
                ffmpegKit_ = nullptr;
            }
        }
    }
}
